﻿using NLog;
using System;
using System.IO;
using System.Timers;

namespace Com.Lancetinc.Evs.Helpers
{
    /// <summary>
    /// 录像控件RadWebCam很多时候没法判断是否真的正在录像，比如能找到摄像头，但是源不可用的时候。或者录到一半摄像头拔了
    /// 本方法使用检测文件变更的方法检测是否真的正在录像
    /// </summary>
    public class RadWebCamRecordingChecker : IDisposable
    {
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

        private FileInfo _fileInfo;
        private readonly Timer _timer;
        private long _lastFileLength = 0;
        private static readonly TimeSpan NotRecordTimeout = TimeSpan.FromSeconds(0.5);

        public event EventHandler<bool> IsRecordingChanged;

        private bool _isRecording = false;

        public bool IsRecording => _timer.Enabled && _isRecording;

        public RadWebCamRecordingChecker(string file)
        {
            _fileInfo = new FileInfo(file);
            _timer = new Timer(100);
            _timer.Elapsed += _timer_Elapsed;
        }

        public void UpdateFile(string file)
        {
            Stop();
            _fileInfo = new FileInfo(file);
        }

        public void Start()
        {
            _isRecording = false;
            if (_fileInfo.Exists)
                _lastFileLength = _fileInfo.Length;
            else
                _lastFileLength = 0;
            _timer.Start();
        }

        public void Stop()
        {
            _timer.Stop();
            _isRecording = false;
            _lastFileLength = 0;
        }

        public bool CheckNow()
        {
            var fi = _fileInfo;
            fi.Refresh();
            if (!fi.Exists || fi.Length == 0)
            {
                return UpdateIsRecording(false);
            }

            var fl = fi.Length;
            if (fl > _lastFileLength)
            {
                _lastFileLength = fl;
                return UpdateIsRecording(true);
            }

            _lastFileLength = fl;
            if (DateTime.Now - fi.LastWriteTime < NotRecordTimeout)
            {
                return UpdateIsRecording(true);
            }

            return UpdateIsRecording(false);
        }

        private bool UpdateIsRecording(bool isRecording)
        {
            if (_isRecording == isRecording)
                return isRecording;

            _isRecording = isRecording;
            Logger.Info($"IsRecordingChanged:{isRecording},file={_fileInfo.Name}");
            IsRecordingChanged?.Invoke(this, isRecording);
            return isRecording;
        }

        private void _timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            CheckNow();
        }

        /// <inheritdoc />
        public void Dispose()
        {
            Stop();
        }
    }
}